#ifndef __UIME_H__
#define __UIME_H__
#include "UEdit.h"
// IME FUNCTION
#include <dimm.h>

class UIMEControl : public VUIControl
{
	enum EIMESKIN
	{
		IME_COMP = 0,
		IME_CANDIDATE,
		IME_BOTTOM,
	};

	enum 
	{
		COMP_PADDING = 3,
		CAND_PADDING = 3,
		VERT_PADDING = 3,
	};
public:
	UIMEControl();
	virtual ~UIMEControl();

	void UpdateRect();
protected:
	virtual BOOL IsIMEControl() const { return TRUE;}
	virtual BOOL OnCreate();
	virtual void OnDestroy();
	virtual void OnRender(const VPoint& offset, const VRect &updateRect);
	virtual void OnMouseDown(const VPoint& pt, UINT nClickCnt, UINT uFlags);
	virtual void OnMouseUp(const VPoint& pt, UINT uFlags);
	virtual void OnMouseDragged(const VPoint& position, UINT flags);
	virtual void OnTimer(float fDeltaTime);
	VSprite m_spBackgroundSkin;
	float m_fTime;
	BOOL m_bCaretOn;
};

// input method editor wrapper.

class UIME
{
	friend class UIMEControl;
public:
	enum
	{
		MAX_COMP_BUFFER = 256,
		MAX_CANDLIST = 10,
	};

	struct KeyboardLayer
	{
		HKL hKL;
		IUTexture* IconTexture;
		char szImeFile[MAX_PATH];
	};

	struct CCandList
    {
        WCHAR awszCandidate[MAX_CANDLIST][256];
      //  CUniBuffer HoriCand; // Candidate list string (for horizontal candidate window)
        int   nFirstSelected; // First character position of the selected string in HoriCand
        int   nHoriSelectedLen; // Length of the selected string in HoriCand
        DWORD dwCount;       // Number of valid entries in the candidate list
        DWORD dwSelection;   // Currently selected candidate entry relative to page top
        DWORD dwPageSize;
        int   nReadingError; // Index of the error character
        bool  bShowWindow;   // Whether the candidate list window is visible
        RECT  rcCandidate;   // Candidate rectangle computed and filled each time before rendered
    };

	struct IMEContext
	{
		std::vector<KeyboardLayer> KeyboardLayers;
	};
public:
	
	static BOOL Initialize();
	static void Shutdown();

	static BOOL EnableIME();
	static void DisableIME();
	static BOOL InitImmApi();
	static BOOL ProcessIMEMessage(UINT nMsg, UINT wParam, UINT lParam);
	static BOOL ProcessIMENotify(UINT wParam, UINT lParam );
	static void UpdateCurrentKL();
	static inline BOOL IsComposing() { return sm_CandList.bShowWindow &&  sm_bEnabled; }
	static BOOL sm_bInited;
	static HMODULE sm_hIMM32;
	static IMEContext* sm_ImeContext;
	static INPUTCONTEXT* (WINAPI* ImmLockIMC)( HIMC );
    static BOOL (WINAPI* ImmUnlockIMC)( HIMC );
    static LPVOID (WINAPI* ImmLockIMCC)( HIMCC );
    static BOOL (WINAPI* ImmUnlockIMCC)( HIMCC );
    static BOOL (WINAPI* ImmDisableTextFrameService)( DWORD );
    static LONG (WINAPI* ImmGetCompositionStringW)( HIMC, DWORD, LPVOID, DWORD );
    static DWORD (WINAPI* ImmGetCandidateListW)( HIMC, DWORD, LPCANDIDATELIST, DWORD );
    static HIMC (WINAPI* ImmGetContext)( HWND );
    static BOOL (WINAPI* ImmReleaseContext)( HWND, HIMC );
    static HIMC (WINAPI* ImmAssociateContext)( HWND, HIMC );
    static BOOL (WINAPI* ImmGetOpenStatus)( HIMC );
    static BOOL (WINAPI* ImmSetOpenStatus)( HIMC, BOOL );
    static BOOL (WINAPI* ImmGetConversionStatus)( HIMC, LPDWORD, LPDWORD );
    static HWND (WINAPI* ImmGetDefaultIMEWnd)( HWND );
    static UINT (WINAPI* ImmGetIMEFileNameA)( HKL, LPSTR, UINT );
    static UINT (WINAPI* ImmGetVirtualKey)( HWND );
    static BOOL (WINAPI* ImmNotifyIME)( HIMC, DWORD, DWORD, DWORD );
    static BOOL (WINAPI* ImmSetConversionStatus)( HIMC, DWORD, DWORD );
    static BOOL (WINAPI* ImmSimulateHotKey)( HWND, DWORD );
    static BOOL (WINAPI* ImmIsIME)( HKL );
	static UINT (WINAPI* ImmGetDescriptionW)(HKL, LPWSTR, UINT uBufLen);

	 static UINT (WINAPI * GetReadingString)( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT );
    static BOOL (WINAPI * ShowReadingWindow)( HIMC, BOOL );

private:
	 static UINT WINAPI _GetReadingString( HIMC, UINT, LPWSTR, PINT, BOOL*, PUINT ) { return 0; }
    static BOOL WINAPI _ShowReadingWindow( HIMC, BOOL ) { return FALSE; }
	
	static void StartComposition();
	static void EndComposition();
	static void SendCompoStr();
	static void UpdateControlRect();
	static BOOL InitKeyboardLayer();
	static void InstallInputLayer(HKL hKL);
	static HKL sm_hCurKL;
	static HMODULE sm_hCurIME;
	static UIMEControl* sm_ImeCtrl;
	static int sm_nCompCaret;
	static WCHAR sm_wszCompBuffer[MAX_COMP_BUFFER];
	static BYTE  sm_byCompStringAttr[MAX_COMP_BUFFER];
	static CCandList sm_CandList;
	static BOOL		sm_bVertCandList;
	static BOOL		sm_bEnabled;
};




#endif 